package com.sxt.netty.server.codec;

import java.util.List;

import com.sxt.common.Message;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

/**
 * 自定义解码器
 * 
 * @program: SpringBoot+Netty+Redis
 * @Date: 2020/09/23 09:20
 * @Author: luolin
 * @Description:
 */
public class MsgDecoder extends ByteToMessageDecoder {

	@Override
	protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
		Object o = decode(ctx, in);
		if (o != null) {
			out.add(o);
		}
	}

	private Object decode(ChannelHandlerContext ctx, ByteBuf in) {
		// 可读长度readableBytes必须大于基本长度才处理
		if (in.readableBytes() < Message.BYTE_BASE) {
			// 长度短了，数据包不完整，需要等待后面的包来
			// FrameDecoder： return null就是等待后面的包，return一个解码的对象就是向下传递。
			return null;
		}

		// 防止socket字节流攻击
		if (in.readableBytes() > Message.BYTE_SOCKET) {
			in.skipBytes(in.readableBytes());
		}

		// 获取帧头
		String head = ByteBufUtil.hexDump(in.readBytes(Message.BYTE_FRAME_HEAD));
		if (!Message.HEAD_FLAG.equalsIgnoreCase(head)) {
			// 找不到帧头,丢弃多余数据
			return null;
		}
		return in;
	}

}
